package Logica;

import java.util.LinkedList;

import General.Constantes;
import Logica.Enemigos.Enemigo;
import Logica.PowerUps.PowerUp;

/**
 * Esta clase almacena los enemigos y los powerups que estan visibles. Ademas mantiene las
 * posiciones del mapa que estan visibles. Se utiliza una Lista provista por java.
 * 
 * @author Mariano Rodecker
 * @author Matias Varela
 * 
 */
public class MapaVisible {

	/* ################## ATRIBUTOS DE INSTANCIA ######################## */
	protected int inicio, fin, limite;
	protected Mapa mapa;
	protected LinkedList<Enemigo> enemigos;
	protected LinkedList<PowerUp> powerups;
	protected LinkedList<Proyectil> proyectiles;

	protected Mario mario;

	/* ################## CONSTRUCTOR ######################## */
	/**
	 * Constructor para un Mapa Visible, el cual esta constituido por un Mapa. Ademas recibe como
	 * parametro la posicion de inicio y fin iniciales.
	 * 
	 * @param m
	 * @param inicio
	 * @param fin
	 */
	public MapaVisible(Mapa m, int inicio, int fin) {
		this.mapa = m;
		this.inicio = inicio;
		this.fin = fin;
		this.limite = inicio - 32 * 5;
		enemigos = new LinkedList<Enemigo>(); // lista de Enemigos visibles
		powerups = new LinkedList<PowerUp>(); // lista de powerups visibles
		proyectiles = new LinkedList<Proyectil>(); // lista de powerups visibles
	}

	/* ################## COMANDOS ######################## */
	public void setMario(Mario m) {
		this.mario = m;
	}

	/**
	 * Mueve el MapaVisible.
	 */
	public void moverMapaV() {
		this.inicio += 1;
		this.fin += 1;
		this.limite += 1;

		if (mapa.tieneEnemigos()){
			if (mapa.getEnemigo().getX()<=fin){
				enemigos.add(mapa.getEnemigo());
				mapa.quitarEnemigo();
			}
		}
	}
	/**
	 * Mueve todos los proyectiles visibles.
	 */
	public void moverProyectiles() {
		for (int i = 0; i < proyectiles.size(); i++) {
			if (proyectiles.get(i).isRemovido() || proyectiles.get(i).getX() > fin || proyectiles.get(i).getX()<limite)
				proyectiles.remove(i);
			else {
				proyectiles.get(i).moverse();
				proyectiles.get(i).moverse();
				proyectiles.get(i).moverse();
				proyectiles.get(i).moverse();
			}
		}
	}

	/**
	 * Mueve todos los enemigos visibles.
	 */
	/*
	 * Este metodo no esta verificado aun.
	 */
	public void moverEnemigos() {
		try {
			for (int i = 0; i < enemigos.size(); i++) {
				if (enemigos.get(i) != null) {
					if (enemigos.get(i).isDead() || enemigos.get(i).getX() < limite)
						enemigos.remove(i);
					else
					enemigos.get(i).moverse();
				}

			}
		} catch (java.util.ConcurrentModificationException e1) {
			System.out.println("Error: MapaVisible - moverEnemigos()");
		}

	}

	/*
	 * metodo no verificado aun.
	 */
	public void moverPowerUps() {
		try {
			PowerUp toRemove = null;
			for (PowerUp e : this.powerups) {
				if (e != null) {
					e.moverse();
					if (e.getX() < limite)
						toRemove = e;
				}
			}
			powerups.remove(toRemove);
		} catch (java.util.ConcurrentModificationException e1) {
			System.out.println("Error: MapaVisible - moverPowerups()");
		}
	}

	/*
	 * metodo no verificado aun.
	 */
	public void agregarPowerUp(PowerUp p) {
		p.setY(p.getY() - Constantes.sizeCelda);
		powerups.add(p);
	}

	public void quitarPowerUp(PowerUp p) {
		powerups.remove(p);
	}

	/* ################## CONSULTAS ######################## */
	public Mario getMario() {
		return mario;
	}

	public LinkedList<Enemigo> getEnemigos() {
		return enemigos;
	}

	public LinkedList<PowerUp> getPowerUps() {
		return powerups;
	}

	/**
	 * Retorna la posicion inicial donde el Mapa es Visible
	 * 
	 * @return la posicion inicial donde el Mapa es Visible
	 */
	public int getInicio() {
		return inicio;
	}

	/**
	 * Retorna la posicion final donde el Mapa es Visible
	 * 
	 * @return la posicion final donde el Mapa es Visible
	 */
	public int getFin() {
		return fin;
	}

	/**
	 * Retorna la posicion a partir del cual los enemigos deben dejar de ser visibles.
	 * 
	 * @return la posicion a partir del cual los enemigos deben dejar de ser visibles.
	 */
	public int getLimite() {
		return limite;
	}

	/**
	 * Retorna el mapa .
	 * 
	 * @return el mapa
	 */
	public Mapa getMapa() {
		return mapa;
	}

	public LinkedList<Proyectil> getProyectiles() {
		return proyectiles;
	}

}
